package com.ywd.platform.netty.jt080.po;

import java.util.ArrayList;
import java.util.List;

import java.util.ArrayList;
import java.util.List;

/**
 * 报警类型枚举
 * 基于JT/T808协议标准定义报警位
 */
public enum AlarmType {
    // 基本报警位（0-15）
    EMERGENCY_ALARM(0, 0x0001, "紧急报警,触动报警开关后触发"),
    OVERSPEED_ALARM(1, 0x0002, "超速报警"),
    FATIGUE_DRIVING_ALARM(2, 0x0004, "疲劳驾驶"),
    DANGER_WARNING_ALARM(3, 0x0008, "危险预警"),
    GNSS_ANTENNA_OPEN_ALARM(4, 0x0010, "GNSS天线开路"),
    GNSS_ANTENNA_CUT_ALARM(5, 0x0020, "GNSS天线未接或被剪断"),
    GNSS_ANTENNA_SHORT_ALARM(6, 0x0040, "GNSS天线短路"),
    MAIN_POWER_UNDERVOLTAGE_ALARM(7, 0x0080, "终端主电源欠压"),
    MAIN_POWER_CUT_ALARM(8, 0x0100, "终端主电源掉电"),
    LCD_SCREEN_ERROR_ALARM(9, 0x0200, "终端LCD或显示器故障"),
    TTS_ERROR_ALARM(10, 0x0400, "TTS模块故障"),
    CAMERA_ERROR_ALARM(11, 0x0800, "摄像头故障"),
    ICCARD_MODULE_ERROR_ALARM(12, 0x1000, "道路运输证IC卡模块故障"),
    OVERSPEED_WARNING(13, 0x2000, "超速预警"),
    FATIGUE_DRIVING_WARNING(14, 0x4000, "疲劳驾驶预警"),
    ILLEGAL_DRIVING_ALARM(15, 0x8000, "违规行驶报警"),

    // 扩展报警位（16-31）
    TIRE_PRESSURE_WARNING(16, 0x10000, "胎压预警"),
    RIGHT_TURN_BLIND_SPOT_ALARM(17, 0x20000, "右转盲区异常报警"),
    ACCUMULATED_DRIVING_TIMEOUT(18, 0x40000, "当天累计驾驶超时"),
    OVERTIME_PARKING_ALARM(19, 0x80000, "超时停车"),
    IN_OUT_AREA_ALARM(20, 0x100000, "进出区域"),
    IN_OUT_ROUTE_ALARM(21, 0x200000, "进出路线"),
    ROAD_TRAVEL_TIME_ALARM(22, 0x400000, "路段行驶时间不足/过长"),
    ROUTE_DEVIATION_ALARM(23, 0x800000, "路线偏离报警"),
    VSS_FAULT_ALARM(24, 0x1000000, "车辆VSS故障"),
    FUEL_EXCEPTION_ALARM(25, 0x2000000, "车辆油量异常"),
    VEHICLE_THEFT_ALARM(26, 0x4000000, "车辆被盗(通过车辆防盗器)"),
    ILLEGAL_IGNITION_ALARM(27, 0x8000000, "车辆非法点火"),
    ILLEGAL_DISPLACEMENT_ALARM(28, 0x10000000, "车辆非法位移"),
    COLLISION_WARNING(29, 0x20000000, "碰撞预警"),
    ROLLOVER_WARNING(30, 0x40000000, "侧翻预警"),

    // 保留报警位
    RESERVED_2(31, 0x800000000L, "保留报警位2");

    private final int bitPosition;
    private final long bitMask;
    private final String description;

    AlarmType(int bitPosition, long bitMask, String description) {
        this.bitPosition = bitPosition;
        this.bitMask = bitMask;
        this.description = description;
    }

    public int getBitPosition() {
        return bitPosition;
    }

    public long getBitMask() {
        return bitMask;
    }

    public String getDescription() {
        return description;
    }

    /**
     * 根据位位置获取报警类型
     *
     * @param bitPosition 位位置
     * @return 对应的报警类型，如果未找到则返回null
     */
    public static AlarmType getByBitPosition(int bitPosition) {
        for (AlarmType alarm : values()) {
            if (alarm.bitPosition == bitPosition) {
                return alarm;
            }
        }
        return null;
    }

    /**
     * 根据位掩码获取报警类型
     *
     * @param bitMask 位掩码
     * @return 对应的报警类型，如果未找到则返回null
     */
    public static AlarmType getByBitMask(long bitMask) {
        for (AlarmType alarm : values()) {
            if (alarm.bitMask == bitMask) {
                return alarm;
            }
        }
        return null;
    }

    /**
     * 检查给定的报警位掩码中是否包含当前报警类型
     *
     * @param alarmBits 报警位掩码
     * @return 如果包含则返回true，否则返回false
     */
    public boolean isSetIn(long alarmBits) {
        return (alarmBits & bitMask) != 0;
    }

    /**
     * 将当前报警类型添加到报警位掩码中
     *
     * @param alarmBits 原始报警位掩码
     * @return 添加后的报警位掩码
     */
    public long addTo(long alarmBits) {
        return alarmBits | bitMask;
    }

    /**
     * 从报警位掩码中移除当前报警类型
     *
     * @param alarmBits 原始报警位掩码
     * @return 移除后的报警位掩码
     */
    public long removeFrom(long alarmBits) {
        return alarmBits & ~bitMask;
    }

    /**
     * 解析报警位掩码，返回所有设置的报警类型描述
     *
     * @param alarmBits 报警位掩码
     * @return 报警描述列表
     */
    public static List<String> parseAlarmBits(long alarmBits) {
        List<String> alarms = new ArrayList<>();
        for (AlarmType alarm : values()) {
            if (alarm.isSetIn(alarmBits)) {
                alarms.add(alarm.getDescription());
            }
        }
        return alarms;
    }
}
